package com.example.chandao.common.base;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.example.chandao.common.exception.BusinessException;
import com.github.pagehelper.PageHelper;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
public class BaseController {

    /**
     * 获取请求属性
     */
    protected ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }


    /**
     * 获取Request
     */
    protected HttpServletRequest getRequest() {
        return getRequestAttributes().getRequest();
    }


    /**
     * 获取Response
     */
    protected HttpServletResponse getResponse() {
        return getRequestAttributes().getResponse();
    }


    /**
     * 设置请求分页
     */
    protected void startPage() {
        String pageNumStr = getRequest().getParameter("pageNum");
        String pageSizeStr = getRequest().getParameter("pageSize");
        int pageNum = StrUtil.isNotBlank(pageNumStr) ? Integer.parseInt(pageNumStr) : 1;
        int pageSize = StrUtil.isNotBlank(pageSizeStr) ? Integer.parseInt(pageSizeStr) : 20;
        PageHelper.startPage(pageNum, pageSize, Boolean.TRUE);
    }


    /**
     * 获取用户Token
     */
    protected String getToken() {
        return StpUtil.getTokenValue();
    }


    /**
     * 获取用户ID
     */
    protected String getUserId() {
        return StpUtil.getLoginIdAsString();
    }



    /**
     * 导出Excel：通过EasyExcel导出：实体类需要注解
     */
    protected void exportExcel(List<?> dataList, Class<?> clazz) {
        HttpServletResponse response = getResponse();
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("测试", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 头的策略
            WriteCellStyle headStyle = new WriteCellStyle();
            WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short) 10);
            headStyle.setWriteFont(headWriteFont);
            HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy();
            styleStrategy.setHeadWriteCellStyle(headStyle);
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), clazz).registerWriteHandler(styleStrategy).sheet("模板").doWrite(dataList);
        } catch (Exception e) {
            //log.error("【导出Excel】异常：" + e);
        }
    }

    /**
     * 导出文件
     */
    protected void exportFile(File file) {
        HttpServletResponse response = getResponse();
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(file.getName(), StandardCharsets.UTF_8));
        response.setContentType("application/octet-stream");
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            FileUtil.writeToStream(file, outputStream);
        } catch (Exception e) {
            //log.error("错误信息：", e);
        } finally {
            try {
                assert outputStream != null;
                outputStream.close();
            } catch (IOException e) {
                //log.error("错误信息：", e);
            }
        }
    }

    /**
     * 使用的HuTool的工具
     */
    protected void exportExcelByMap(List<Map<String, Object>> rows) {
        ExcelWriter writer = ExcelUtil.getWriter(Boolean.TRUE);
        this.exportExcelByMap(writer, rows);
    }

    /**
     * 导出Excel：使用的HuTool的工具
     */
    protected void exportExcelByMap(ExcelWriter writer, List<Map<String, Object>> rows) {
        writer = ObjectUtil.defaultIfNull(writer, ExcelUtil.getWriter(Boolean.TRUE));
        writer.write(rows, Boolean.TRUE);
        HttpServletResponse response = getResponse();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=test.xlsx");
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            log.error("【导出Excel】异常：" + e);
            throw new BusinessException("系统错误，请联系管理员处理");
        }
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

}
